{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%capture\n",
    "!apt-get install cmake\n",
    "!apt-get install zlib1g-dev\n",
    "!pip install gym[atari]\n",
    "!pip install JSAnimation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/sachin/miniconda3/lib/python3.6/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
      "  from ._conv import register_converters as _register_converters\n",
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "# import cPickle as pickle\n",
    "import matplotlib.pyplot as plt\n",
    "from JSAnimation.IPython_display import display_animation\n",
    "from matplotlib import animation\n",
    "import gym\n",
    "\n",
    "from keras.models import Sequential\n",
    "from keras.layers import Dense, Conv2D, MaxPool2D, Flatten\n",
    "from keras.optimizers import rmsprop\n",
    "import keras.backend as K\n",
    "\n",
    "\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "env = gym.make(\"Pong-v0\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['NOOP', 'FIRE', 'RIGHT', 'LEFT', 'RIGHTFIRE', 'LEFTFIRE']"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "env.env.get_action_meanings()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "action_space = [0,2,3] #[No-op, up, down]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def display_frames_as_gif(frames):\n",
    "    \"\"\"\n",
    "    Displays a list of frames as a gif, with controls\n",
    "    \"\"\"\n",
    "    #plt.figure(figsize=(frames[0].shape[1] / 72.0, frames[0].shape[0] / 72.0), dpi = 72)\n",
    "    patch = plt.imshow(frames[0])\n",
    "    plt.axis('off')\n",
    "\n",
    "    def animate(i):\n",
    "        patch.set_data(frames[i])\n",
    "\n",
    "    anim = animation.FuncAnimation(plt.gcf(), animate, frames = len(frames), interval=50)\n",
    "    display(display_animation(anim, default_mode='once'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<script language=\"javascript\">\n",
       "  /* Define the Animation class */\n",
       "  function Animation(frames, img_id, slider_id, interval, loop_select_id){\n",
       "    this.img_id = img_id;\n",
       "    this.slider_id = slider_id;\n",
       "    this.loop_select_id = loop_select_id;\n",
       "    this.interval = interval;\n",
       "    this.current_frame = 0;\n",
       "    this.direction = 0;\n",
       "    this.timer = null;\n",
       "    this.frames = new Array(frames.length);\n",
       "\n",
       "    for (var i=0; i<frames.length; i++)\n",
       "    {\n",
       "     this.frames[i] = new Image();\n",
       "     this.frames[i].src = frames[i];\n",
       "    }\n",
       "    document.getElementById(this.slider_id).max = this.frames.length - 1;\n",
       "    this.set_frame(this.current_frame);\n",
       "  }\n",
       "\n",
       "  Animation.prototype.get_loop_state = function(){\n",
       "    var button_group = document[this.loop_select_id].state;\n",
       "    for (var i = 0; i < button_group.length; i++) {\n",
       "        var button = button_group[i];\n",
       "        if (button.checked) {\n",
       "            return button.value;\n",
       "        }\n",
       "    }\n",
       "    return undefined;\n",
       "  }\n",
       "\n",
       "  Animation.prototype.set_frame = function(frame){\n",
       "    this.current_frame = frame;\n",
       "    document.getElementById(this.img_id).src = this.frames[this.current_frame].src;\n",
       "    document.getElementById(this.slider_id).value = this.current_frame;\n",
       "  }\n",
       "\n",
       "  Animation.prototype.next_frame = function()\n",
       "  {\n",
       "    this.set_frame(Math.min(this.frames.length - 1, this.current_frame + 1));\n",
       "  }\n",
       "\n",
       "  Animation.prototype.previous_frame = function()\n",
       "  {\n",
       "    this.set_frame(Math.max(0, this.current_frame - 1));\n",
       "  }\n",
       "\n",
       "  Animation.prototype.first_frame = function()\n",
       "  {\n",
       "    this.set_frame(0);\n",
       "  }\n",
       "\n",
       "  Animation.prototype.last_frame = function()\n",
       "  {\n",
       "    this.set_frame(this.frames.length - 1);\n",
       "  }\n",
       "\n",
       "  Animation.prototype.slower = function()\n",
       "  {\n",
       "    this.interval /= 0.7;\n",
       "    if(this.direction > 0){this.play_animation();}\n",
       "    else if(this.direction < 0){this.reverse_animation();}\n",
       "  }\n",
       "\n",
       "  Animation.prototype.faster = function()\n",
       "  {\n",
       "    this.interval *= 0.7;\n",
       "    if(this.direction > 0){this.play_animation();}\n",
       "    else if(this.direction < 0){this.reverse_animation();}\n",
       "  }\n",
       "\n",
       "  Animation.prototype.anim_step_forward = function()\n",
       "  {\n",
       "    this.current_frame += 1;\n",
       "    if(this.current_frame < this.frames.length){\n",
       "      this.set_frame(this.current_frame);\n",
       "    }else{\n",
       "      var loop_state = this.get_loop_state();\n",
       "      if(loop_state == \"loop\"){\n",
       "        this.first_frame();\n",
       "      }else if(loop_state == \"reflect\"){\n",
       "        this.last_frame();\n",
       "        this.reverse_animation();\n",
       "      }else{\n",
       "        this.pause_animation();\n",
       "        this.last_frame();\n",
       "      }\n",
       "    }\n",
       "  }\n",
       "\n",
       "  Animation.prototype.anim_step_reverse = function()\n",
       "  {\n",
       "    this.current_frame -= 1;\n",
       "    if(this.current_frame >= 0){\n",
       "      this.set_frame(this.current_frame);\n",
       "    }else{\n",
       "      var loop_state = this.get_loop_state();\n",
       "      if(loop_state == \"loop\"){\n",
       "        this.last_frame();\n",
       "      }else if(loop_state == \"reflect\"){\n",
       "        this.first_frame();\n",
       "        this.play_animation();\n",
       "      }else{\n",
       "        this.pause_animation();\n",
       "        this.first_frame();\n",
       "      }\n",
       "    }\n",
       "  }\n",
       "\n",
       "  Animation.prototype.pause_animation = function()\n",
       "  {\n",
       "    this.direction = 0;\n",
       "    if (this.timer){\n",
       "      clearInterval(this.timer);\n",
       "      this.timer = null;\n",
       "    }\n",
       "  }\n",
       "\n",
       "  Animation.prototype.play_animation = function()\n",
       "  {\n",
       "    this.pause_animation();\n",
       "    this.direction = 1;\n",
       "    var t = this;\n",
       "    if (!this.timer) this.timer = setInterval(function(){t.anim_step_forward();}, this.interval);\n",
       "  }\n",
       "\n",
       "  Animation.prototype.reverse_animation = function()\n",
       "  {\n",
       "    this.pause_animation();\n",
       "    this.direction = -1;\n",
       "    var t = this;\n",
       "    if (!this.timer) this.timer = setInterval(function(){t.anim_step_reverse();}, this.interval);\n",
       "  }\n",
       "</script>\n",
       "\n",
       "<div class=\"animation\" align=\"center\">\n",
       "    <img id=\"_anim_imgWSBVVUHBQIUPUWZT\">\n",
       "    <br>\n",
       "    <input id=\"_anim_sliderWSBVVUHBQIUPUWZT\" type=\"range\" style=\"width:350px\" name=\"points\" min=\"0\" max=\"1\" step=\"1\" value=\"0\" onchange=\"animWSBVVUHBQIUPUWZT.set_frame(parseInt(this.value));\"></input>\n",
       "    <br>\n",
       "    <button onclick=\"animWSBVVUHBQIUPUWZT.slower()\">&#8211;</button>\n",
       "    <button onclick=\"animWSBVVUHBQIUPUWZT.first_frame()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animWSBVVUHBQIUPUWZT.previous_frame()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animWSBVVUHBQIUPUWZT.reverse_animation()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animWSBVVUHBQIUPUWZT.pause_animation()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animWSBVVUHBQIUPUWZT.play_animation()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animWSBVVUHBQIUPUWZT.next_frame()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animWSBVVUHBQIUPUWZT.last_frame()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animWSBVVUHBQIUPUWZT.faster()\">+</button>\n",
       "  <form action=\"#n\" name=\"_anim_loop_selectWSBVVUHBQIUPUWZT\" class=\"anim_control\">\n",
       "    <input type=\"radio\" name=\"state\" value=\"once\" checked> Once </input>\n",
       "    <input type=\"radio\" name=\"state\" value=\"loop\" > Loop </input>\n",
       "    <input type=\"radio\" name=\"state\" value=\"reflect\" > Reflect </input>\n",
       "  </form>\n",
       "</div>\n",
       "\n",
       "\n",
       "<script language=\"javascript\">\n",
       "  /* Instantiate the Animation class. */\n",
       "  /* The IDs given should match those used in the template above. */\n",
       "  (function() {\n",
       "    var img_id = \"_anim_imgWSBVVUHBQIUPUWZT\";\n",
       "    var slider_id = \"_anim_sliderWSBVVUHBQIUPUWZT\";\n",
       "    var loop_select_id = \"_anim_loop_selectWSBVVUHBQIUPUWZT\";\n",
       "    var frames = new Array(0);\n",
       "    \n",
       "  frames[0] = \"\"\n",
       "  frames[1] = \"\"\n",
       "  frames[2] = \"\"\n",
       "  frames[3] = \"\"\n",
       "  frames[4] = \"\"\n",
       "  frames[5] = \"\"\n",
       "  frames[6] = \"\"\n",
       "  frames[7] = \"\"\n",
       "  frames[8] = \"\"\n",
       "  frames[9] = \"\"\n",
       "  frames[10] = \"\"\n",
       "  frames[11] = \"\"\n",
       "  frames[12] = \"\"\n",
       "  frames[13] = \"\"\n",
       "  frames[14] = \"\"\n",
       "  frames[15] = \"\"\n",
       "  frames[16] = \"\"\n",
       "  frames[17] = \"\"\n",
       "  frames[18] = \"\"\n",
       "  frames[19] = \"\"\n",
       "  frames[20] = \"\"\n",
       "  frames[21] = \"\"\n",
       "  frames[22] = \"\"\n",
       "  frames[23] = \"\"\n",
       "  frames[24] = \"\"\n",
       "  frames[25] = \"\"\n",
       "  frames[26] = \"\"\n",
       "  frames[27] = \"\"\n",
       "  frames[28] = \"\"\n",
       "  frames[29] = \"\"\n",
       "  frames[30] = \"\"\n",
       "  frames[31] = \"\"\n",
       "  frames[32] = \"\"\n",
       "  frames[33] = \"\"\n",
       "  frames[34] = \"\"\n",
       "  frames[35] = \"\"\n",
       "  frames[36] = \"\"\n",
       "  frames[37] = \"\"\n",
       "  frames[38] = \"\"\n",
       "  frames[39] = \"\"\n",
       "  frames[40] = \"\"\n",
       "  frames[41] = \"\"\n",
       "  frames[42] = \"\"\n",
       "  frames[43] = \"\"\n",
       "  frames[44] = \"\"\n",
       "  frames[45] = \"\"\n",
       "  frames[46] = \"\"\n",
       "  frames[47] = \"\"\n",
       "  frames[48] = \"\"\n",
       "  frames[49] = \"\"\n",
       "  frames[50] = \"\"\n",
       "  frames[51] = \"\"\n",
       "  frames[52] = \"\"\n",
       "  frames[53] = \"\"\n",
       "  frames[54] = \"\"\n",
       "  frames[55] = \"\"\n",
       "  frames[56] = \"\"\n",
       "  frames[57] = \"\"\n",
       "  frames[58] = \"\"\n",
       "  frames[59] = \"\"\n",
       "  frames[60] = \"\"\n",
       "  frames[61] = \"\"\n",
       "  frames[62] = \"\"\n",
       "  frames[63] = \"\"\n",
       "  frames[64] = \"\"\n",
       "  frames[65] = \"\"\n",
       "  frames[66] = \"\"\n",
       "  frames[67] = \"\"\n",
       "  frames[68] = \"\"\n",
       "  frames[69] = \"\"\n",
       "  frames[70] = \"\"\n",
       "  frames[71] = \"\"\n",
       "  frames[72] = \"\"\n",
       "  frames[73] = \"\"\n",
       "  frames[74] = \"\"\n",
       "  frames[75] = \"\"\n",
       "  frames[76] = \"\"\n",
       "  frames[77] = \"\"\n",
       "  frames[78] = \"\"\n",
       "  frames[79] = \"\"\n",
       "  frames[80] = \"\"\n",
       "  frames[81] = \"\"\n",
       "  frames[82] = \"\"\n",
       "  frames[83] = \"\"\n",
       "  frames[84] = \"\"\n",
       "  frames[85] = \"\"\n",
       "  frames[86] = \"\"\n",
       "  frames[87] = \"\"\n",
       "  frames[88] = \"\"\n",
       "  frames[89] = \"\"\n",
       "  frames[90] = \"\"\n",
       "  frames[91] = \"\"\n",
       "  frames[92] = \"\"\n",
       "  frames[93] = \"\"\n",
       "  frames[94] = \"\"\n",
       "  frames[95] = \"\"\n",
       "  frames[96] = \"\"\n",
       "  frames[97] = \"\"\n",
       "  frames[98] = \"\"\n",
       "  frames[99] = \"\"\n",
       "\n",
       "\n",
       "    /* set a timeout to make sure all the above elements are created before\n",
       "       the object is initialized. */\n",
       "    setTimeout(function() {\n",
       "        animWSBVVUHBQIUPUWZT = new Animation(frames, img_id, slider_id, 50, loop_select_id);\n",
       "    }, 0);\n",
       "  })()\n",
       "</script>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "99\n"
     ]
    }
   ],
   "source": [
    "observation = env.reset()\n",
    "cum_reward = 0\n",
    "frames = []\n",
    "r = []\n",
    "for t in range(100):\n",
    "    # Render into buffer. \n",
    "    frames.append(env.render(mode = 'rgb_array'))\n",
    "    p = [0.5, 0.3, 0.2]\n",
    "    a = np.random.choice(3, p=p)\n",
    "    action = action_space[a]\n",
    "    observation, reward, done, info = env.step(action)\n",
    "    r.append(reward)\n",
    "    if done:\n",
    "        break\n",
    "        \n",
    "r = np.array(r)\n",
    "# env.render(close=True)\n",
    "display_frames_as_gif(frames)\n",
    "print(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "gamma = 0.99\n",
    "def discount_rewards(r):\n",
    "    \"\"\" take 1D float array of rewards and compute discounted reward \"\"\"\n",
    "    discounted_r = np.zeros_like(r)\n",
    "    running_add = 0\n",
    "    for t in reversed(range(len(discounted_r))):\n",
    "        if r[t] != 0: running_add = 0 # reset the sum, since this was a game boundary (pong specific!)\n",
    "        running_add =  r[t] + running_add * gamma # belman equation\n",
    "        discounted_r[t] = running_add\n",
    "    return discounted_r\n",
    "\n",
    "def discount_n_standardise(r):\n",
    "    dr = discount_rewards(r)\n",
    "    dr = (dr - dr.mean()) / dr.std()\n",
    "    return dr"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Preprocess image"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def preprocess(I):\n",
    "    \"\"\" prepro 210x160x3 uint8 frame into 6400 (80x80) 1D float vector \"\"\"\n",
    "    I = I[35:195] # crop\n",
    "    I = I[::2,::2,0] # downsample by factor of 2\n",
    "    I[I == 144] = 0 # erase background (background type 1)\n",
    "    I[I == 109] = 0 # erase background (background type 2)\n",
    "    I[I != 0] = 1 # everything else (paddles, ball) just set to 1\n",
    "    return I.astype(np.float)[:,:,None]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Reinforcement Learning\n",
    "\n",
    "It turns out that action 2 makes the racket go up and 3 makes the racket go down. It has 6 actions by default because it's an Atari game, and there were 6 buttons in the controller. See [here](https://ai.stackexchange.com/questions/2449/what-are-different-actions-in-action-space-of-environment-of-pong-v0-game-from) for source of this answer."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def policy_loss(adv_y_true, y_pred):\n",
    "    reward = adv_y_true[:,0]\n",
    "    y_true = adv_y_true[:,1:]\n",
    "    return K.mean(reward*\n",
    "                  K.sparse_categorical_crossentropy(y_true, y_pred), \n",
    "                  axis=-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "conv2d_5 (Conv2D)            (None, 80, 80, 4)         40        \n",
      "_________________________________________________________________\n",
      "max_pooling2d_5 (MaxPooling2 (None, 40, 40, 4)         0         \n",
      "_________________________________________________________________\n",
      "conv2d_6 (Conv2D)            (None, 40, 40, 8)         296       \n",
      "_________________________________________________________________\n",
      "max_pooling2d_6 (MaxPooling2 (None, 20, 20, 8)         0         \n",
      "_________________________________________________________________\n",
      "conv2d_7 (Conv2D)            (None, 20, 20, 12)        876       \n",
      "_________________________________________________________________\n",
      "max_pooling2d_7 (MaxPooling2 (None, 10, 10, 12)        0         \n",
      "_________________________________________________________________\n",
      "conv2d_8 (Conv2D)            (None, 10, 10, 16)        1744      \n",
      "_________________________________________________________________\n",
      "max_pooling2d_8 (MaxPooling2 (None, 5, 5, 16)          0         \n",
      "_________________________________________________________________\n",
      "flatten_2 (Flatten)          (None, 400)               0         \n",
      "_________________________________________________________________\n",
      "dense_2 (Dense)              (None, 10)                4010      \n",
      "_________________________________________________________________\n",
      "dense_3 (Dense)              (None, 3)                 33        \n",
      "=================================================================\n",
      "Total params: 6,999\n",
      "Trainable params: 6,999\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model = Sequential()\n",
    "model.add(Conv2D(4, kernel_size=(3,3), padding='same', activation='relu', input_shape = (80,80,1)))\n",
    "model.add(MaxPool2D(pool_size=(2, 2)))\n",
    "model.add(Conv2D(8, kernel_size=(3,3), padding='same', activation='relu'))\n",
    "model.add(MaxPool2D(pool_size=(2, 2)))\n",
    "model.add(Conv2D(12, kernel_size=(3,3), padding='same', activation='relu'))\n",
    "model.add(MaxPool2D(pool_size=(2, 2)))\n",
    "model.add(Conv2D(16, kernel_size=(3,3), padding='same', activation='relu'))\n",
    "model.add(MaxPool2D(pool_size=(2, 2)))\n",
    "model.add(Flatten())\n",
    "model.add(Dense(10))\n",
    "model.add(Dense(3, activation='softmax'))\n",
    "model.compile(optimizer='rmsprop', loss=policy_loss) #\n",
    "\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "episodes = 0\n",
    "n_episodes = 1000\n",
    "reward_sums = np.zeros(n_episodes)\n",
    "losses = np.zeros(n_episodes)\n",
    "time_taken = np.zeros(n_episodes)\n",
    "reward_sum = 0\n",
    "prev_x = None\n",
    "im_shape = (80, 80, 1)\n",
    "\n",
    "prev_frame = None\n",
    "buffer = 30000\n",
    "xs = np.zeros((buffer,)+im_shape)\n",
    "ys = np.zeros(buffer)\n",
    "rs = np.zeros(buffer)\n",
    "\n",
    "\n",
    "k = 0\n",
    "\n",
    "observation = env.reset()\n",
    "\n",
    "while episodes<n_episodes:\n",
    "    x = preprocess(observation)\n",
    "    xs[k] = x - prev_frame if prev_frame is not None else np.zeros(im_shape)\n",
    "    prev_frame = x\n",
    "    \n",
    "    p = model.predict(xs[k][None,:,:,:])\n",
    "    a = np.random.choice(3, p=p[0])\n",
    "    action = action_space[a]\n",
    "    ys[k] = a\n",
    "    \n",
    "    observation, reward, done, info = env.step(action)\n",
    "    reward_sum += reward\n",
    "    rs[k] = reward\n",
    "    \n",
    "    k += 1\n",
    "    \n",
    "    if done or k==buffer:\n",
    "        reward_sums[episodes] = reward_sum\n",
    "        reward_sum = 0\n",
    "        \n",
    "        \n",
    "        ep_x = xs[:k]\n",
    "        ep_y = ys[:k]\n",
    "        ep_r = rs[:k]\n",
    "        \n",
    "        ep_r = discount_n_standardise(ep_r)\n",
    "        model.fit(ep_x, np.hstack([ep_r, ep_y]), batch_size=512, epochs=1, verbose=0)\n",
    "        \n",
    "        time_taken[episodes] = k\n",
    "        k = 0\n",
    "        prev_frame = None\n",
    "        observation = env.reset()\n",
    "        losses[episodes] = model.evaluate(ep_x, \n",
    "                                          np.hstack([ep_r, ep_y]), \n",
    "                                          batch_size=len(ep_x), \n",
    "                                          verbose=0)\n",
    "        episodes += 1\n",
    "        \n",
    "        if episodes%(n_episodes//20) == 0:\n",
    "            ave_reward = np.mean(reward_sums[max(0,episodes-200):episodes])\n",
    "            ave_loss = np.mean(losses[max(0,episodes-200):episodes])\n",
    "            ave_time = np.mean(time_taken[max(0,episodes-200):episodes])\n",
    "            print('Episode: {0:d}, Average Loss: {1:.4f}, Average Reward: {2:.4f}, Average steps: {3:.4f}'\n",
    "                  .format(episodes, ave_loss, ave_reward, ave_time))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1877650ba8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\nVkU6e3/++uFMdu3QyIWHd2P2ys2MX7SeYDhKKKLp3K6Beau20LVDI9Go5ojdO7LfLu35aNp3rNzU\nxBG7d2LM/LXs17UdvTq3YeHarWxuCnPK/julnfv2jQGuP3EPwhHN4nXbuOKo7vTq3Ib/jVtKMBxl\na3OY+oCPD6as4Jkf9+bTWau57oRe/N/rE5i+YhNv/vxY3pm4jLEL1tG7R0da1/vZrWOrtDKe/XFv\n/jduCe0a6zi4WwfeGr+U9q0CBPw+duvYislLNhKIz5sTiWouOSK2uuZxe3XmwsN2JRiJcnj3jhy3\n144EfC0PzJ3bN/Cb0/fh/EO72f7NvXzNUbw7aRld2zeilOLOs/fne/t24dWxi1mzpZk9u7RlzqrN\nfLexiSuO6sHxe3fmP18v4fKjuvPHd6Zx7J47puW3z85tueXUvbmsT6zuf/3BIfxj1HzWbGnmq7lr\nuf/ig+jesTWfzlrFLh1acc/70znzwK6ccWBXPpi6gltP3Yc7Bk1m3uqtLFizlaN6dWLZ+u2cfuDO\nvDtxOUfv0Yk1m4N0bFPH+q0hGup8aA3tWwXYv2t7Ppq+ks5tG9geDPP0j3vzz68W8ums1Tx8ySHQ\npTtfHfUMm+aNyXlOtjc10aVpEZ1aVcegqy4dO7F3o/l0E16zc/vGgpehvPIne0GfPn30uHHG1pgg\nCIJgjFJqvNa6T750VePDFwRBEHIjgi8IglAjiOALgiDUCCL4giAINYIIviAIQo0ggi8IglAjiOAL\ngiDUCCL4giAINUJZDbxSSq0GFrnIojOwxqPqlCvSxuqhFtopbSwOu2utu+RLVFaC7xal1Dgro80q\nGWlj9VAL7ZQ2lhfi0hEEQagRRPAFQRBqhGoT/IGlrkARkDZWD7XQTmljGVFVPnxBEATBnGqz8AVB\nEAQTqkLwlVJnKqVmKaXmKqVuL3V9nKKU6q6U+lQpNUMpNU0pdXN8eyel1HCl1Jz4347x7Uop9WS8\n3ZOVUr1L2wLrKKX8SqkJSqn34997KaXGxtv4X6VUfXx7Q/z73Pj+nqWstx2UUjsopd5USs2MX9O+\n1XYtlVK3xn+rU5VSryulGqvhWiqlXlRKrVJKTU3ZZvvaKaX6xdPPUUr1K0VbUql4wVdK+YGngbOA\nA4ArlFKFXSescISBX2ut9weOAW6Kt+V2YITWem9gRPw7xNq8d/zf9cCzxa+yY24GZqR8/yvweLyN\n64Fr49uvBdZrrfcCHo+nqxT+Bnyotd4POJRYe6vmWiqlugG/AvporQ8C/MDlVMe1fBk4M2ObrWun\nlOoE/Ak4GjgK+FPiIVEytNYV/Q/oCwxL+X4HcEep6+VR294BTgNmAbvEt+0CzIp/HgBckZI+ma6c\n/wG7EbthTgbeBxSxgS6GheYAAAK1SURBVCuBzGsKDAP6xj8H4ulUqdtgoY3tgQWZda2mawl0A5YA\nneLX5n3gjGq5lkBPYKrTawdcAQxI2Z6WrhT/Kt7Cp+VHl2BpfFtFE3/dPRwYC+ystV4BEP+bWFi2\nUtv+BPA7ILGa947ABq11YoXu1HYk2xjfvzGevtzZA1gNvBR3XT2vlGpDFV1LrfUy4BFgMbCC2LUZ\nT/VdywR2r13ZXdNqEHyjFZMrOvRIKdUWeAu4RWu9KVdSg21l3Xal1LnAKq31+NTNBkm1hX3lTADo\nDTyrtT4c2EqLC8CIimtn3D1xAdAL2BVoQ8y9kUmlX8t8mLWr7NpbDYK/FOie8n03YHmJ6uIapVQd\nMbF/VWs9KL55pVJql/j+XYBV8e2V2PbjgPOVUguB/xBz6zwB7KCUCsTTpLYj2cb4/g7AumJW2CFL\ngaVa67Hx728SewBU07U8FVigtV6ttQ4Bg4Bjqb5rmcDutSu7a1oNgv8NsHc8MqCeWKfRuyWukyOU\nUgp4AZihtX4sZde7QKKHvx8x335i+0/iUQLHABsTr5zlitb6Dq31blrrnsSu1Sda6x8DnwKXxJNl\ntjHR9kvi6cveKtRafwcsUUrtG990CjCdKrqWxFw5xyilWsd/u4k2VtW1TMHutRsGnK6U6hh/Gzo9\nvq10lLpjxKPOlbOB2cA84M5S18dFO44n9so3GZgY/3c2MT/nCGBO/G+neHpFLEJpHjCFWLREydth\no73fA96Pf94D+BqYC7wBNMS3N8a/z43v36PU9bbRvsOAcfHr+TbQsdquJfBnYCYwFfg30FAN1xJ4\nnVi/RIiYpX6tk2sH/DTe3rnANaVul4y0FQRBqBGqwaUjCIIgWEAEXxAEoUYQwRcEQagRRPAFQRBq\nBBF8QRCEGkEEXxAEoUYQwRcEQagRRPAFQRBqhP8HdIlhPKiZk/4AAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x112b33cc0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(losses[:episodes])\n",
    "plt.plot(np.convolve(losses[:episodes], np.ones((100,))/100, mode='valid'))\n",
    "plt.show()\n",
    "\n",
    "plt.plot(reward_sums[:episodes])\n",
    "plt.plot(np.convolve(reward_sums[:episodes], np.ones((100,))/100, mode='valid'))\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "observation = env.reset()\n",
    "cum_reward = 0\n",
    "frames = []\n",
    "prev_frame = None\n",
    "for t in range(5000):\n",
    "    x = preprocess(observation) \n",
    "    diff = x - prev_frame if prev_frame is not None else np.zeros(im_shape)\n",
    "    p = model.predict(diff[None,:,:,:])\n",
    "    prev_frame = x\n",
    "    a = np.random.choice(3, p=p[0])\n",
    "    action = action_space[a]\n",
    "    \n",
    "    # Render into buffer. \n",
    "    frames.append(env.render(mode = 'rgb_array'))\n",
    "    observation, reward, done, info = env.step(action)\n",
    "    if done:\n",
    "        break\n",
    "        \n",
    "# env.render(close=True)\n",
    "display_frames_as_gif(frames)\n",
    "print(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
